package yueyong.salarymanagement.module.business.salary.controller;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import yueyong.salarymanagement.common.anno.NoValidPrivilege;
import yueyong.salarymanagement.common.constant.ResponseCodeConst;
import yueyong.salarymanagement.common.domain.ResponseDTO;
import yueyong.salarymanagement.constant.SwaggerTagConst;
import yueyong.salarymanagement.module.business.salary.dao.EmployeeSalaryDao;
import yueyong.salarymanagement.module.business.salary.domain.dto.*;
import yueyong.salarymanagement.module.business.salary.domain.entity.EmployeeSalaryEntity;
import yueyong.salarymanagement.module.business.salary.domain.vo.*;
import yueyong.salarymanagement.module.business.salary.service.EmployeeSalaryService;
import yueyong.salarymanagement.module.business.salary.service.UserCompanyService;
import yueyong.salarymanagement.module.system.login.domain.RequestTokenBO;
import yueyong.salarymanagement.util.SmartRequestTokenUtil;

import javax.validation.Valid;
import java.sql.Timestamp;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Copyright: yueyong (c) 2022
 *
 * @author he.shaorong
 * @version 1.0
 * @date 2022/2/12
 */
@RestController
@Api(tags = {SwaggerTagConst.Admin.BUSINESS})
public class SendSalaryRecordsController {

    @Autowired
    private EmployeeSalaryService employeeSalaryService;

    @Autowired
    private EmployeeSalaryDao employeeSalaryDao;

    @Autowired
    private SalaryRecordsController resendSalarySlip;

    @Autowired
    private UserCompanyService userCompanyService;

    @ApiOperation(value = "发送记录 默认", notes = "返回当年 所有薪资记录")
    @PostMapping("/user/querySalarySlipSendRecordsDefault")
    @NoValidPrivilege
    public ResponseDTO<List<SendSalarySlipRecordsVO>> querySalarySlipSendRecordsDefault(@Valid @RequestBody QuerySendSalarySlipRecordsDTO querySendSalarySlipRecordsDTO) {

        List<SendSalarySlipRecordsVO> resultList = Lists.newArrayList();

        RequestTokenBO requestToken = SmartRequestTokenUtil.getRequestUser();
        Long uid = requestToken.getRequestUserId();

        Timestamp startDate = new Timestamp(querySendSalarySlipRecordsDTO.getStartDate());
        Timestamp endDate = new Timestamp(querySendSalarySlipRecordsDTO.getEndDate());

        List<SalayIdVO> salaryIdList = employeeSalaryService.getSpecifyDateSalaryId(startDate, endDate, uid);

        for (SalayIdVO salaryId: salaryIdList) {
            SendSalarySlipRecordsVO salarySlipRecordsVO = new SendSalarySlipRecordsVO();
            salarySlipRecordsVO.setSalaryId(salaryId.getSalaryId());


            List<EmployeeSalaryEntity> employeeSalaryEntityList = employeeSalaryService.getEmployeeSalaryEntityBySalaryId(uid, salaryId.getSalaryId());

            List<EmployeeSalaryEntity> sendedSalaryEntityList = employeeSalaryEntityList.stream().filter(item -> item.getState() != -1 && item.getState() != -10).collect(Collectors.toList());

            if(sendedSalaryEntityList != null && sendedSalaryEntityList.size()>0) {
                salarySlipRecordsVO.setPayDate(sendedSalaryEntityList.get(0).getPayDate().getTime());
                salarySlipRecordsVO.setSendTime(sendedSalaryEntityList.get(0).getMsgSendTime().getTime());

                long count = sendedSalaryEntityList.stream().map(data -> data.getEmployeeId()).distinct().count();
                salarySlipRecordsVO.setEmployeeCount((int)count);
                resultList.add(salarySlipRecordsVO);
            }

        }

        return ResponseDTO.succData(resultList);
    }

    @ApiOperation(value = "发送记录 -选择一条记录", notes = "返回一条记录对应所有的薪资条发送结果")
    @PostMapping("/user/querySalarySlipDetail")
    @NoValidPrivilege
    public ResponseDTO<List<SalarySlipEmployeeSendDetailVO>> querySalarySlipDetail(@Valid @RequestBody SalarySlipDetailDTD salarySlipDetailDTD) {

        List<SalarySlipEmployeeSendDetailVO> resultList = Lists.newArrayList();

        RequestTokenBO requestToken = SmartRequestTokenUtil.getRequestUser();
        Long uid = requestToken.getRequestUserId();

        List<EmployeeSalaryEntity> employeeSalaryEntityList = employeeSalaryService.getEmployeeSalaryEntityBySalaryId(uid, salarySlipDetailDTD.getSalaryId());

        List<EmployeeSalaryEntity> sendedSalaryEntityList = employeeSalaryEntityList.stream()
                .filter(item -> item.getState() != -1 && item.getState() != -10 && item.getSendType() == salarySlipDetailDTD.getSendType()).collect(Collectors.toList());

        if(sendedSalaryEntityList != null && sendedSalaryEntityList.size()>0) {
            return ResponseDTO.succData(sendedSalaryEntityList.stream().map( item -> buildSalarySlipEmployeeSendDetailVO(item)).collect(Collectors.toList()));
        }

        return ResponseDTO.succ();
    }


    @GetMapping("/user/queryEmployeeSalaryDetail")
    @ApiOperation(value = "发送记录 - 选择一条记录 - 查看", notes = "返回某个员工发放薪资的详情")
    @NoValidPrivilege
    public ResponseDTO<EmployeeSalarySlipDetailVO> queryEmployeeSalaryDetail(@RequestParam long salaryId, @RequestParam long employee) {
        RequestTokenBO requestToken = SmartRequestTokenUtil.getRequestUser();
        Long uid = requestToken.getRequestUserId();

        List<EmployeeSalaryEntity> employeeSalaryEntityList = employeeSalaryService.getEmployeeSalaryEntityBySalaryIdAndEmployeeId(uid, salaryId, employee);
        EmployeeSalaryEntity sendedSalaryEntity = employeeSalaryEntityList.stream()
                .filter(item -> item.getState() == -1 || item.getState() == 6 ).findFirst().orElse(null);
        if(sendedSalaryEntity != null) {
            EmployeeSalarySlipDetailVO vo = new EmployeeSalarySlipDetailVO();
            vo.setEmployeeName(sendedSalaryEntity.getEmployeeName());
            vo.setPayAmount(sendedSalaryEntity.getPayAmount());
            vo.setPayTime(sendedSalaryEntity.getPayDate().getTime());
            vo.setPayAmountIndex(sendedSalaryEntity.getPayItemId());

            String detail = sendedSalaryEntity.getSalaryItems();

            JSONObject jsonObject2 = JSONObject.parseObject(detail);
            EmployeeSalaryDataVO employeeSalaryDataVO = JSONObject.toJavaObject(jsonObject2, EmployeeSalaryDataVO.class);
            employeeSalaryDataVO.getSalaryData().sort(Comparator.comparing(ItemData::getItemId));
            vo.setEmployeeSalaryDetail(employeeSalaryDataVO);
            return ResponseDTO.succData(vo);
        } else {
            return ResponseDTO.wrap(ResponseCodeConst.NOT_EXISTS);
        }
    }

    @PostMapping("/user/modifySalarySlipDetail")
    @ApiOperation(value = "发送记录 - 选择一条记录 - 修改 - 保存", notes = "修改结果")
    @NoValidPrivilege
    public ResponseDTO modifySalarySlipDetail(@Valid @RequestBody EmployeeSalarySlipDetailDTO dto) {
        RequestTokenBO requestToken = SmartRequestTokenUtil.getRequestUser();
        Long uid = requestToken.getRequestUserId();

        List<EmployeeSalaryEntity> employeeSalaryEntityList = employeeSalaryService
                .getEmployeeSalaryEntityBySalaryIdAndEmployeeId(uid, dto.getSalaryId(), dto.getEmployeeId());
        EmployeeSalaryEntity sendedSalaryEntity = employeeSalaryEntityList.stream()
                .filter(item -> item.getState() == -1  || item.getState() == 6 ).findFirst().orElse(null);
        if(sendedSalaryEntity != null) {
            sendedSalaryEntity.setPayAmount(dto.getPayAmount());

            String itemsStr = sendedSalaryEntity.getSalaryItems();
            JSONObject jsonObject = JSONObject.parseObject(itemsStr);
            SalaryImportData employeeSalaryDataVO = JSONObject.toJavaObject(jsonObject, SalaryImportData.class);
            employeeSalaryDataVO.setSalaryData(dto.getEmployeeSalaryDetail().getSalaryData());


            //转成JSON对象
            JSONObject jsonObject2 = (JSONObject) JSONObject.toJSON(employeeSalaryDataVO);
            String jsonStr = jsonObject2.toJSONString();
            sendedSalaryEntity.setSalaryItems(jsonStr);
            int result = employeeSalaryDao.updateById(sendedSalaryEntity);
            if(result >0) {
                return ResponseDTO.succ();
            } else return ResponseDTO.wrap(ResponseCodeConst.DATABASE_ERROR);

        } else {
            return ResponseDTO.wrap(ResponseCodeConst.NOT_EXISTS);
        }
    }

    @PostMapping("/user/recallSalarySlip")
    @ApiOperation(value = "发送记录 - 选择一条记录 - 撤回", notes = "撤回结果")
    @NoValidPrivilege
    public ResponseDTO recallSalarySlip(@Valid @RequestBody SalarySlipEmployeeRecordDTD dto) {
        RequestTokenBO requestToken = SmartRequestTokenUtil.getRequestUser();
        Long uid = requestToken.getRequestUserId();

        int sendType = dto.getSendType();
        long salaryId = dto.getSalaryId();
        long employeeId = dto.getEmployeeId();

        List<EmployeeSalaryEntity> employeeSalaryEntityList = employeeSalaryService.getEmployeeSalaryEntityBySalaryIdAndEmployeeId(uid, salaryId, employeeId);
        EmployeeSalaryEntity sendedSalaryEntity = employeeSalaryEntityList.stream()
                .filter(item -> item.getState() != -1 && item.getState() != 6 && item.getSendType() == sendType).findFirst().orElse(null);
        if(sendedSalaryEntity != null) {

            sendedSalaryEntity.setState(6);//撤回
            sendedSalaryEntity.setStateReason("recall");
            int sendResult = employeeSalaryService.updateEmployeeSalaryEntity(sendedSalaryEntity);
            if(sendResult > 0) {
                return ResponseDTO.succ();
            } else {
                return ResponseDTO.wrap(ResponseCodeConst.FAILED);
            }

        } else {
            return ResponseDTO.wrap(ResponseCodeConst.NOT_EXISTS);
        }
    }

    @PostMapping("/user/resendSalarySlip")
    @ApiOperation(value = "发送记录 - 选择一条记录 - 重发", notes = "重发结果")
    @NoValidPrivilege
    public ResponseDTO resendSalarySlip(@Valid @RequestBody SalarySlipEmployeeRecordDTD dto) {
        RequestTokenBO requestToken = SmartRequestTokenUtil.getRequestUser();
        Long uid = requestToken.getRequestUserId();

        int sendType = dto.getSendType();
        long salaryId = dto.getSalaryId();
        long employeeId = dto.getEmployeeId();

        List<EmployeeSalaryEntity> employeeSalaryEntityList = employeeSalaryService.getEmployeeSalaryEntityBySalaryIdAndEmployeeId(uid, salaryId, employeeId);
        EmployeeSalaryEntity sendedSalaryEntity = employeeSalaryEntityList.stream()
                .filter(item -> item.getState() != -1 && item.getSendType() == sendType).findFirst().orElse(null);
        if(sendedSalaryEntity != null) {

            SalarySendDTO salarySendDTO = getSalarySendDTO(sendedSalaryEntity, sendType);
            boolean sendResult = resendSalarySlip.handleSendSalaryTask(sendedSalaryEntity, salarySendDTO, true);
            if(sendResult) {
                return ResponseDTO.succ();
            } else {
                return ResponseDTO.wrap(ResponseCodeConst.FAILED);
            }

        } else {
            return ResponseDTO.wrap(ResponseCodeConst.NOT_EXISTS);
        }
    }


    private SalarySlipEmployeeSendDetailVO buildSalarySlipEmployeeSendDetailVO(EmployeeSalaryEntity entity) {
        SalarySlipEmployeeSendDetailVO vo = new SalarySlipEmployeeSendDetailVO();

        vo.setEmployeeId(entity.getEmployeeId());
        vo.setEmployeeName(entity.getEmployeeName());
        vo.setSendResult(entity.getSendType());
        vo.setReason(entity.getStateReason());
        vo.setSendType(entity.getSendType());
        vo.setSendResult(entity.getState());
        vo.setPayTime(entity.getPayDate().getTime());
        vo.setSendTime(entity.getMsgSendTime().getTime());
        vo.setMobilePhone(entity.getMobilePhone());
        vo.setEmail(entity.getEmailAddress());
        return vo;
    }

    private SalarySendDTO getSalarySendDTO(EmployeeSalaryEntity sendedSalaryEntity, int sendType) {
        SalarySendDTO salarySendDTO = new SalarySendDTO();
        salarySendDTO.setCompanyName(getUserCompanyName());
        salarySendDTO.setPayDate(sendedSalaryEntity.getPayDate().getTime());

        switch (sendType) {
            case 1:
                salarySendDTO.setSendWeChat(true);
                break;
            case 2:
                salarySendDTO.setEmailMessage(true);
                break;
            case 3:
                salarySendDTO.setSendEntWeChat(true);
                break;
            case 4:
                salarySendDTO.setShortMessage(true);
                break;
            default:
                break;
        }
        return salarySendDTO;
    }


    public String getUserCompanyName() {
        List<UserCompanyVO> userCompanyVOList = userCompanyService.queryUserCompany();
        if (userCompanyVOList == null || userCompanyVOList.size() == 0) {
            return "【未设置公司名】";
        }
        return userCompanyVOList.get(0).getCompanyName();
    }

}
